package com.hd.trans.network.component

import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.OnLifecycleEvent
import com.hd.trans.network.ApiServiceManager
import com.hd.trans.network.RxSchedulers
import com.hd.trans.network.bean.TaskResultRequest
import com.hd.trans.network.bean.TaskResultResponse
import com.hd.trans.network.bean.textToVoice.Text2VoiceRequest
import com.hd.trans.network.bean.textToVoice.Text2VoiceResponse
import com.hd.trans.share.DownloadArg
import com.hd.trans.share.Md5Util
import com.hd.trans.share.UrlDownloadRequest
import com.hd.trans.ui.service.NetDisposableObserver3
import com.hd.trans.utils.MediaFileUtil
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.io.File

/**
 * 文字转语音接口："api/v4/sub/ae-task/mac/text-to-voice"
 * https://gitlab.huduntech.com/php/img-convert/-/wikis/sub/ae-task/mac/text-to-voice
 */
class TtsManager {
    private var filePath: String = ""
    private var disposable: Disposable? = null
    private var isAllowDownload: Boolean = false
    var isTaskRunning: Boolean = false
    private var isDestroy: Boolean = false
    private val mHandler = Handler(Looper.getMainLooper())
    private var text2VoiceTaskId: String = ""
    private var text2VoiceContent: String? = null
    private var mTtsListener: SdkListener? = null
    var mTtsConfig: TtsConfig = TtsConfig.createConfig()
        .setTtsCode("zh")
        .setPitch(1f)
        .setType("mp3")

    init {
        //默认配置
    }

    /**
     * 页面销毁 终止回调
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    private fun destroy() {
        onDestroy()
    }

    fun onDestroy() {
        cancelTask()
        isDestroy = true
    }

    fun cancelTask(){
        text2VoiceTaskId = ""
        disposable?.dispose()
        mHandler.removeCallbacksAndMessages(null)
    }

    fun setTtsListener(listener: TtsListener){
        mTtsListener = listener
    }

    /**
     * 该方法可以重置TtsConfig参数
     */
    fun createText2VoiceTask(
        text: String,
        ttsCode: String? = null,
        isAllowDownload: Boolean = false,
    ) {
        if(!TextUtils.isEmpty(ttsCode)){
            mTtsConfig.ttsCode = ttsCode
        }
        showLogDebug("text2Voice text = $text")
        this.isAllowDownload = isAllowDownload

        onProgress(text, 0)
        textToVoice(text, mTtsConfig.ttsCode, mTtsConfig.pitch)
    }

    private fun textToVoice(text: String?, ttsCode: String?, pitch: Float = 1f){
        isTaskRunning = true
        if(text == null || text.trim().isEmpty()){
            onFail(-1,"内容不能为空")
            return
        }
        if(ttsCode == null || ttsCode.trim().isEmpty()){
            onFail(-1,"该语言暂不支持语音播放")
            return
        }
        //
        val fileName = Md5Util.getMD5(text + ttsCode + pitch) + ".${mTtsConfig.type}"
        filePath = MediaFileUtil.getMediaDownloadPath() + fileName
        if(File(filePath).exists()){
            showLogDebug("本地文件：filePath = $filePath")
            text2VoiceTaskId = "10000"
            onProgress(text2VoiceTaskId, 10)
            onSuccess(text, filePath)
            return
        }

        ApiServiceManager.v4ApiService.textToVoice(
            Text2VoiceRequest(
                text = text,
                lang = ttsCode,
                pitch = pitch,
                type = "mp3")
                .makeRequestBody(mTtsConfig.userInfoBean))
            .compose(RxSchedulers.applySchedulers())
            .subscribe(NetDisposableObserver3(object :
                NetDisposableObserver3.NetCallBack<Text2VoiceResponse> {
                override fun onResponse(response: Text2VoiceResponse) {
                    if(response.code == 10000) { //任务创建成功
                        if(response.task_id.isEmpty()){
                            onFail(response.code,"文字转语音任务创建失败")
                            return
                        }
                        text2VoiceTaskId = response.task_id
                        text2VoiceContent = text
                        showLogDebug("text2VoiceTaskId = $text2VoiceTaskId")
                        onProgress(text2VoiceTaskId, 10)
                        mHandler.removeCallbacks(mQueryText2VoiceRunnable)
                        mHandler.post(mQueryText2VoiceRunnable)
                    }else{
                        onFail(response.code,response.message)
                    }
                }

                override fun onError(code: Int, msg: String) {
                    onFail(code, msg)
                }

                override fun onTokenInvalid(msg: String) {
                    onFail(-1, msg)
                }
            }))
    }

    private val mQueryText2VoiceRunnable: Runnable = object : Runnable {
        override fun run() {
            if(isDestroy){
                return
            }
            queryTaskResult(text2VoiceTaskId, queryAgain = {
                mHandler.removeCallbacks(this)
                mHandler.postDelayed(this, 2000)
            }){
                showLogDebug("text2Voice Url = ${it.video_url}")
                onProgress("",80)

                if(isAllowDownload){
                    //下载文件到本地
                    downloadFile(it.video_url, filePath)
                }else{
                    //直接反馈网络媒体地址
                    onSuccess(text2VoiceContent?:"", it.video_url)
                }
            }
        }
    }

    private fun queryTaskResult(task_id: String?, queryAgain: (() -> Unit)?, resultBack: ((TaskResultResponse) -> Unit)?) {
        if(task_id.isNullOrEmpty()) {
            return
        }
        object : Observer<TaskResultResponse> {
            override fun onSubscribe(d: Disposable) {}
            override fun onNext(response: TaskResultResponse) {
                when (response.code) {
                    10000 -> {
                        //任务处理成功,返回结果
                        resultBack?.invoke(response)
                    }
                    100602 -> {
                        //任务正在处理中,继续查询
                        queryAgain?.invoke()
                    }
                    101221 -> {
                        //文本合法性验证不通过
                        onFail(response.code, "AI回答内容的合法性验证不通过")
                    }
                    else -> {
                        onFail(response.code, response.message)
                    }
                }
            }

            override fun onError(e: Throwable) {
                onFail(-1, e.toString())
            }
            override fun onComplete() {}
        }

        // 创建 Disposable 对象
        ApiServiceManager.v4ApiService.queryTask(
            TaskResultRequest(task_id = task_id).makeRequestBody(null)
        ).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<TaskResultResponse> {
                override fun onSubscribe(d: Disposable) {
                    disposable = d
                }
                override fun onNext(response: TaskResultResponse) {
                    when (response.code) {
                        10000 -> {
                            //任务处理成功,返回结果
                            resultBack?.invoke(response)
                        }
                        100602 -> {
                            //任务正在处理中,继续查询
                            queryAgain?.invoke()
                        }
                        101221 -> {
                            //文本合法性验证不通过
                            onFail(response.code, "AI回答内容的合法性验证不通过")
                        }
                        else -> {
                            onFail(response.code, response.message)
                        }
                    }
                }

                override fun onError(e: Throwable) {
                    onFail(-1, e.toString())
                }
                override fun onComplete() {}
            })

        // 取消请求
        if (Thread.currentThread().isInterrupted) {
            disposable?.dispose()
        }

    }

    /**
     * 下载文件
     * @param downUrl 下载地址
     * @param savePath 保存路径（绝对路径），为空则保存到默认路径
     */
    private fun downloadFile(downUrl: String, savePath: String? = null) {
        val mediaFilePath = if(savePath.isNullOrEmpty()) {
            //解析私有地址
            val array = downUrl.split("?")
            val name = if (array.isEmpty()) {
                downUrl.substring(downUrl.lastIndexOf("/") + 1)
            }else{
                array[0].substring(array[0].lastIndexOf("/") + 1)
            }
            MediaFileUtil.getMediaDownloadPath() + name
        }else{
            savePath
        }
        //FileUtils.clearFolderSubFiles(File(videoFilePath).parentFile)// 删除缓存的文件
        val downloadThread = UrlDownloadRequest(null, downUrl, mediaFilePath)
        downloadThread.request(object : UrlDownloadRequest.DownloadCallback {
            override fun onDownloadStart(downloadArg: DownloadArg?) {
            }

            override fun onDownloadProgress(downloadArg: DownloadArg?, progress: Int) {
            }

            override fun onDownloadError(downloadArg: DownloadArg?) {
                onFail(-1, "下载失败")
            }

            override fun onDownloadComplete(downloadArg: DownloadArg?) {
                //下载完成
                showLogDebug("下载完成 Url = $mediaFilePath")
                onSuccess(text2VoiceContent?:"", mediaFilePath)
            }
        })
    }

    private fun showLogDebug(logMsg: String){
        //if(TranslationInterior.isDebug())
            Log.d("TtsManager", logMsg)
    }

    private fun onFail(code: Int = -1, msg: String) {
        if(isDestroy){
            return
        }
        isTaskRunning = false
        onProgress("",-1)
        mHandler.post {
            mTtsListener?.onFail(code, msg)
        }
    }

    private fun onSuccess(msg: String, path: String) {
        if(isDestroy){
            return
        }

        isTaskRunning = false
        onProgress("",100)
        mHandler.post {
            mTtsListener?.onSuccess(text2VoiceTaskId, msg, path)
        }
    }

    private fun onProgress(msg: String, progress: Int) {
        if(isDestroy){
            return
        }
        mHandler.post {
            mTtsListener?.onProgress(msg, progress)
        }
    }
}